package mailclient.client;

import java.io.IOException;
import java.nio.charset.CharacterCodingException;
import java.util.ArrayList;
import mailcommon.entities.*;
import mailcommon.helpers.FunctionType;

public class Operator {

    private Client client;
    private Viewer viewer;

    public Operator()
            throws IOException {
        client = new Client();
        viewer = new Viewer();
    }

    public void run()
            throws IOException {
        String s;
        while (true) {
            viewer.writeln("Enter command:");
            s = viewer.readln();
            execute(s);
        }
    }

    private void execute(String s) throws IOException {
        CommandType cmd = CommandType.parse(s);
        if (cmd != null) {
            switch (cmd) {
                case Exit: {
                    System.exit(1);
                }
                case Help: {
                    viewer.showHelp();
                }
            }
        } else {
            FunctionType func = FunctionType.parse(s);
            if (func != null) {
                client.writeToChannel(s);
                String read = client.readFromChannel();
                if (read.equals("OK")) {
                    switch (func) {
                        case Login: {
                            login();
                            break;
                        }
                        case Registration: {
                            registration();
                            break;
                        }
                        case Logout: {
                            logout();
                            break;
                        }
                        case SendLetter: {
                            sendLetter();
                            break;
                        }
                        case CheckNewLetters: {
                            loadLetters();
                            break;
                        }
                        case ReadLetter: {
                            readLetter();
                            break;
                        }
                        case LoadLetters: {
                            loadLetters();
                            break;
                        }
                    }
                } else {
                    viewer.writeln(read);
                }
            } else {
                viewer.unknownCommand();
            }
        }
    }

    private void registration()
            throws IOException {
        viewer.createUser();
        User user = viewer.parseUser();
        client.writeObject(user);
        viewer.createAddress();
        String address = viewer.readln();
        client.writeObject(address);
        viewer.writeln(client.readFromChannel());
    }

    private void login()
            throws IOException {
        client.writeToChannel(viewer.requestAddress());
        viewer.writeln(client.readFromChannel());
    }

    private void logout()
            throws IOException {
        viewer.writeln(client.readFromChannel());
    }

    private void sendLetter()
            throws IOException {
        String[] vals = viewer.createLetter();
        String s = "";
        for (String v : vals) {
            s += v + "@@";
        }
        client.writeObject(s);
        viewer.writeln(client.readFromChannel());
    }

    private void loadLetters()
            throws CharacterCodingException, IOException {
        Object obj = client.readObject();
        try {
            ArrayList<Letter> letters = (ArrayList<Letter>) obj;
            viewer.showLetters(letters);
        } catch (ClassCastException ex) {
            viewer.writeln((String) obj);
        }
    }

    private void readLetter()
            throws IOException {
        viewer.requestLetterId();
        int id = viewer.getLetterId();
        client.writeToChannel(String.valueOf(id));
        Object obj = client.readObject();
        try {
            Letter letter = (Letter) obj;
            viewer.showLetter(letter);
        } catch (ClassCastException ex) {
            viewer.writeln((String) obj);
        }
    }
}
